home *** CD-ROM | disk | FTP | other *** search
- (*
- For MS/PC-DOS versions of Turbo only. Known to work correctly with version
- 3.01A of Turbo Pascal, should work with earlier versions.
-
- The inline string comparison functions included here provide high-speed
- replacements for those in the Turbo run-time library. If you have been
- using the earlier version of CMPSTR.INC, please note the following:
- (1) A second routine has been added which accepts literals, constants,
- and function results as parameters, as well as string variables.
- (2) To avoid confusion, I have kept the name of the old routine the
- same, and given the new one the name CompareStr.
- (3) The new version of CompStr is slightly faster than the old.
-
- Both routines offer two advantages over the standard library routines.
- (1) In standard Turbo, the statement "TrueFalse := (String1 = String2)"
- will tell you if the strings are equal, but if they aren't you have to
- execute a second statement to find out why. These return Less, Equal,
- or Greater in one swoop. (2) Speed. I have tested CompStr against an
- essentially equivalent function using the standard library routines:
- the tests indicated that CompStr will always be at least 2.5 times
- faster; on average about 3.5 to 4 times faster. (In the worst case--
- 2 255-character strings, 1st one different--CompStr tested 27+ times
- faster.) Tests of CompareStr showed that it is 1.4 to 2.9 times faster
- than an equivalent function coded in Turbo, probably about twice as fast
- on average.
- One last note. As given here, these functions return a result of a
- scalar type: Comparer = ( Less, Equal, Greater). If you wish, you can
- change this to 'Byte' and interpret the results as follows:
- 0 : String1 < String2; - Less -
- 1 : String1 = String2; - Equal -
- 2 : String1 > String2; - Greater -
- To test for "<=", check for "not Greater" or "< 2"; to test for ">=",
- check for "not Less" or "> 0".
-
- Special thanks to David B. Rein for suggestions on optimizing the code.
-
- Written by Brian Foley CompuServe ID # [76317,3247]
- Last update: 5/12/86
-
- Updated for use in PibTerm v4.0 by Phil Burns.
- Principal change: Handle null strings correctly.
-
- How CompStr and CompareStr use registers:
- AL initially indicates which string is longer and is coded the same way as
- the function result: 0 => S1 is shorter; 1 => S1 is the same length as S2;
- 2 => S1 is longer. The strings will be compared up to the end of the
- shorter string, whose length is put into CX. If the strings evaluate as
- equal up to that point, then by definition the longer string is greater,
- and BL will already contain the function result. Here's a quick example:
- Result := CompareStr( 'BILL', 'BILLY' );
- Here, CX will be set initially to 4 = Length(S1), and AL will be set to 0,
- to indicate that S1 is shorter. The comparison will go to 4 characters,
- and the strings will evaluate as equal up to that point. Since AL already
- equals 0, it gives us the correct result: 0 => S1 < S2. In cases where the
- strings do not evaluate as equal, the length record will be wiped out, and
- AL will be set to 0 or 2, depending upon the outcome of the comparison.
-
- *)
-
- FUNCTION CompareStr( S1, S2 : AnyStr ) : Comparer;
-
- { IMPORTANT NOTE: S1 and S2 *must* be of type String[ 255 ] }
-
- BEGIN
-
- INLINE(
- $1E { PUSH DS ;Save data segment register}
- {;}
- /$30/$ED { XOR CH,CH ;Clear register holding S1's length}
- /$88/$E8 { MOV AL,CH ;S1 < S2 is initial default.}
- {;}
- /$8C/$D2 { MOV DX,SS ;Move SS into ES}
- /$8E/$C2 { MOV ES,DX ;}
- /$8E/$DA { MOV DS,DX ;and DS}
- /$8D/$BE/>S2 { LEA DI,[BP+>S2] ;ES:DI points to S2}
- /$8A/$1D { MOV BL,[DI] ;BL is length of S2}
- /$47 { INC DI}
- /$8D/$B6/>S1 { LEA SI,[BP+>S1] ;DS:SI points to S1}
- /$8A/$0C { MOV CL,[SI] ;CL is length of S1}
- /$46 { INC SI}
- /$38/$D9 { CMP CL,BL ;See if lengths are equal}
- /$74/$06 { JE EqualLen ;Yes}
- {;}
- /$72/$0A { JB Compare ;If Length( S2 ) < Length( S1 ),}
- /$FE/$C0 { INC AL ;assume equal for the present.}
- /$88/$D9 { MOV CL,BL ;Only compare up to min of lengths.}
- {;}
- /$FE/$C0 {EqualLen: INC AL ;Set to return strings equal.}
- /$38/$E9 { CMP CL,CH ;See if lengths zero -- immediate}
- /$74/$0B { JE Return ;return (with strings equal) if so.}
- {;}
- /$FC {Compare: CLD ;Forward direction for compare}
- /$F3/$A6 { REPE CMPSB ;Perform comparison}
- /$74/$06 { JE Return ;Return if strings equal.}
- /$B0/$02 { MOV AL,2 ;Mark S1 > S2.}
- /$77/$02 { JA Return ;}
- /$30/$C0 { XOR AL,AL ;Mark S1 < S2.}
- {;}
- /$88/$86/$04/$02 {Return: MOV [BP+$204],AL ;Store function return value.}
- {;}
- /$1F { POP DS}
- );
-
- END;